﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Win32Utils
{
    public static class Win32Api
    {
        /// <summary>
        /// 鼠标相关
        /// </summary>
        public static class Mouse
        {
            /// <summary>
            /// 获取鼠标在屏幕上的位置
            /// </summary>
            /// <returns>位置</returns>
            [DllImport("user32.dll")]
            public static extern bool GetCursorPos(out Point pt);
        }

        /// <summary>
        /// 窗口操作
        /// </summary>
        public static class Window
        {

            /// <summary>
            /// 释放资源
            /// </summary>
            /// <param name="hwnd"></param>
            /// <param name="hdc"></param>
            /// <returns></returns>
            [DllImport("User32.dll ")]
            public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);

            /// <summary>
            /// 获取整个窗口的画图
            /// </summary>
            /// <param name="hwnd">窗口句柄</param>
            /// <returns>DC句柄</returns>
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowDC(IntPtr hwnd);

            /// <summary>
            /// 屏幕坐标到客户区坐标
            /// </summary>
            /// <param name="hwnd">窗口句柄</param>
            /// <param name="p"></param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern bool ScreenToClient(IntPtr hwnd, ref Point p);

            /// <summary>
            /// 查找指定点窗口的句柄
            /// </summary>
            /// <param name="pHwd">父句柄</param>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern IntPtr WindowFromPoint(Point p);

            /// <summary>
            ///  查找顶级窗口句柄
            /// </summary>
            /// <param name="className">类名</param>
            /// <param name="titleName">标题</param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern IntPtr FindWindow(string className, string titleName);

            /// <summary>
            ///    查找子窗口句柄
            /// </summary>
            /// <param name="hwndParent">要查找窗口的父句柄</param>
            /// <param name="hwndChildAfter">从这个窗口后开始查找</param>
            /// <param name="className">窗口类名</param>
            /// <param name="title">窗口标题</param>
            /// <returns>找到返回窗口句柄，没找到返回0</returns>
            [DllImport("user32.dll")]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string className, string title);

            /// <summary>
            /// 枚举窗口
            /// </summary>
            /// <param name="lpEnumFunc"></param>
            /// <param name="lParam"></param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
            public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);

            /// <summary>
            /// 改变指定子窗口的父窗口
            /// </summary>
            /// <param name="hwndChild">子窗口句柄</param>
            /// <param name="newParent">新的父窗口句柄 如果该参数是NULL，则桌面窗口就成为新的父窗口</param>
            /// <returns>如果函数成功，返回值为子窗口的原父窗口句柄；如果函数失败，返回值为NULL</returns>
            [DllImport("user32.dll")]
            public static extern IntPtr SetParent(IntPtr hwndChild, IntPtr newParent);

            /// <summary>
            /// 显示窗口异步
            /// </summary>
            /// <param name="hWnd">窗口句柄</param>
            /// <param name="cmdShow">显示方式</param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
            [DllImport("user32.dll")]
            public static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
            public const int SW_SHOW = 5;
            public const int SW_HIDE = 0;
            public const int WS_SHOWNORMAL = 1;

            /// <summary>
            /// 激活窗口
            /// </summary>
            /// <param name="hWnd">激活窗口</param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern bool SetForegroundWindow(IntPtr hWnd);

            /// <summary>
            /// 销毁一个窗口
            /// </summary>
            /// <param name="hWnd">窗口句柄</param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern int DestroyWindow(IntPtr hWnd);

            /// <summary>
            /// 该函数返回指定窗口的边框矩形的尺寸。该尺寸以相对于屏幕坐标左上角的屏幕坐标给出
            /// </summary>
            /// <param name="hwnd">窗口句柄</param>
            /// <param name="rect">指向一个RECT结构的指针，该结构接收窗口的左上角和右下角的屏幕坐标</param>
            [DllImport("user32.dll")]
            public static extern void GetWindowRect(IntPtr hwnd, ref Rectangle rect);

            /// <summary>
            /// 设置窗口位置大小 以及置顶窗口
            /// </summary>
            /// <param name="hWnd">窗口句柄</param>
            /// <param name="hWndlnsertAfter">置顶参数（HWND_TOP 。。。）</param>
            /// <param name="x">坐标</param>
            /// <param name="y"></param>
            /// <param name="cx">宽高</param>
            /// <param name="cy"></param>
            /// <param name="flag">SWP标示</param>
            [DllImport("user32.dll")]
            public static extern void SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int x, int y, int cx, int cy, uint flag);
            public const int HWND_TOP = 0; // 在前面
            public const int HWND_BOTTOM = 1; // 在后面
            public const int HWND_TOPMOST = -1; // 在前面, 位于任何顶部窗口的前面
            public const int HWND_NOTOPMOST = -2; // 在前面, 位于其他顶部窗口的后面}

            // 不改变大小
            public const UInt32 SWP_NOSIZE = 0x0001;
            // 不改变位置
            public const UInt32 SWP_NOMOVE = 0x0002;

            /// <summary>
            /// 获取窗口相关信息
            /// </summary>
            public const int WS_EX_TOPMOST = 0x00000008;
            [DllImport("user32.dll")]
            public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
        }

        /// <summary>
        /// hook 相关
        /// </summary>
        public static class Hook
        {
            /// <summary>
            /// hook 事件
            /// </summary>
            /// <param name="eventMin">事件最小值</param>
            /// <param name="eventMax">事件最大值</param>
            /// <param name="obj">一般为null</param>
            /// <param name="winEventProc">事件过程</param>
            /// <param name="idProcess"></param>
            /// <param name="idThread"></param>
            /// <param name="dwflage"></param>
            /// <returns></returns>
            [DllImport("user32.dll")]
            public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, object obj,
                Action<IntPtr, int, IntPtr, long, long, int, int> winEventProc, int idProcess, int idThread, uint dwflage);
        }

        /// <summary>
        /// 消息相关
        /// </summary>
        public static class Message
        {
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern IntPtr SendMessageTimeout(IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags flags, uint timeout, out IntPtr result);

            [Flags]
            public enum SendMessageTimeoutFlags : uint
            {
                SMTO_ABORTIFHUNG = 2,
                SMTO_BLOCK = 1,
                SMTO_ERRORONEXIT = 0x20,
                SMTO_NORMAL = 0,
                SMTO_NOTIMEOUTIFNOTHUNG = 8
            }
        }

    }
}
